package com.agrm.category.service.impl;

import com.agrm.category.mapper.CategoryMapper;
import com.agrm.category.service.CategoryService;
import com.agrm.model.category.pojo.Category;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper , Category> implements CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    /**
     * 获取树形结构
     *
     * @param id id
     * @return Category
     */
    @Override
    public Category getTreeById(Integer id) {
        //获取完整的分类树
        List<Category> categories = listTree();
        //递归截取分类树
        return findTreeById(id,categories);
    }

    /**
     * 根据父分类ID获取直接子分类（只查询下一级，不递归）
     * @param parentId 父分类ID
     * @return 直接子分类列表
     */
    @Override
    public List<Category> getChildrenByParentId(Integer parentId) {
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Category::getParentId, parentId)
                   .orderByAsc(Category::getSort); // 按排序字段升序排列
        
        return categoryMapper.selectList(queryWrapper);
    }

    /**
     * 获取所有一级分类（parent_id为1的分类）
     * @return 一级分类列表
     */
    @Override
    public List<Category> getFirstLevelCategories() {
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Category::getParentId, 1)
                   .orderByAsc(Category::getSort); // 按排序字段升序排列
        
        return categoryMapper.selectList(queryWrapper);
    }


    /**
     * 获取完整的树形结构
     * @return List<Category>
     */
    @Override
    public List<Category> listTree() {
        //把所有的分类取出
        List<Category> categories = categoryMapper.selectList(null);
        if(categories.isEmpty()){
            throw new RuntimeException("异常错误，请联系管理员解决");
        }

        return makeListToTree(categories);
    }


    /**
     * 批量删除
     * @param ids
     * @return
     */
    @Override
    public boolean deleteByIds(List<Integer> ids) {
        for (Integer id : ids) {
            if(!removeById(id)){
                return false;
            }
        }
        return true;
    }


    /**
     * 把list转换成树形结构
     * @param categories 分类列表
     * @return List<Category> 树形结构
     */
    private List<Category> makeListToTree(List<Category> categories) {
        //按照id存入到map中  并找到根节点
        HashMap<Integer , Category> maps = new HashMap<>();
        List<Category> roots = new ArrayList<>();
        for (Category category : categories) {
            maps.put(category.getId() , category);
        }
        //遍历节点 生成树
        for (Category category : maps.values()) {
            if(category.getParentId() == null){
                roots.add(category);
            }else {
                Category parent = maps.get(category.getParentId());
                if (parent == null){
                    throw new RuntimeException("异常错误，请联系管理员解决");
                }
                if(parent.getChildren() == null){
                    parent.setChildren(new ArrayList<>());
                }
                parent.getChildren().add(category);
            }
        }
        return roots;
    }


    /**
     * 根据id查找树形结构
     * @param id 从该点进行截取
     * @param categories 完整的分类树
     * @return  Category
     */
    private Category findTreeById(Integer id, List<Category> categories) {
        //递归
        for (Category category : categories) {
            System.out.print(category.getId() + "-->");
            if(category.getId().equals(id)){
                return category;
            }
            if(category.getChildren() != null){
                Category tree = findTreeById(id, category.getChildren());
                if(tree != null){
                    return tree;
                }
            }
        }
        return null;
    }
}
